package com.dlc.shop.live.api.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dlc.shop.bean.enums.LiveRoomStatusType;
import com.dlc.shop.bean.enums.ProdStatusEnums;
import com.dlc.shop.bean.event.EsProductCouponInfoEvent;
import com.dlc.shop.bean.event.EsSearchProdEvent;
import com.dlc.shop.bean.model.ShopDetail;
import com.dlc.shop.bean.param.EsProductParam;
import com.dlc.shop.bean.param.LiveRoomParam;
import com.dlc.shop.bean.vo.search.EsProductSearchVO;
import com.dlc.shop.bean.vo.search.ProductSearchVO;
import com.dlc.shop.common.bean.AliLive;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.response.ServerResponseEntity;
import com.dlc.shop.common.util.PageParam;
import com.dlc.shop.common.wukongim.constant.WuKongConstant;
import com.dlc.shop.config.ShopConfig;
import com.dlc.shop.live.common.constant.PlayBackType;
import com.dlc.shop.live.common.dto.LiveRoomDto;
import com.dlc.shop.live.common.service.LiveRoomProdService;
import com.dlc.shop.live.common.service.LiveRoomService;
import com.dlc.shop.live.common.util.AliLiveUtil;
import com.dlc.shop.live.common.vo.LiveRoomProdVO;
import com.dlc.shop.live.common.vo.LiveRoomVO;
import com.dlc.shop.service.SegmentService;
import com.dlc.shop.service.ShopDetailService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @author lhd
 * @date 2020-08-05 08:53:17
 */
@RestController
@RequestMapping("/live/liveRoom")
@Tag(name = "直播接口")
@AllArgsConstructor
public class LiveRoomController {

    private final LiveRoomService liveRoomService;
    private final LiveRoomProdService liveRoomProdService;
    private final ApplicationEventPublisher eventPublisher;
    private final ShopConfig shopConfig;
    private final ShopDetailService shopDetailService;
    private final SegmentService segmentService;
    private static final int NON_SORT = 24;

    @GetMapping("/page")
    @Operation(summary = "直播间列表信息", description = "直播间列表信息")
    public ServerResponseEntity<IPage<LiveRoomDto>> getLiveRoomPage(PageParam<LiveRoomDto> page, LiveRoomParam liveRoomParam) {
        // 如果type为空，则为搜索直播信息
        if (Objects.isNull(liveRoomParam.getSearchType()) && StrUtil.isBlank(liveRoomParam.getName())) {
            liveRoomParam.setSearchType(1);
            liveRoomParam.setName("");
        }
        return ServerResponseEntity.success(liveRoomService.pageRoomAndDetail(page, liveRoomParam));
    }

    @GetMapping("/getLiveRoomInfo")
    @Operation(summary = "根据房间id获取直播间信息")
    @Parameters({
            @Parameter(name = "roomId", description = "直播间id")
    })
    public ServerResponseEntity<LiveRoomVO> getLiveRoomInfo(@RequestParam(value = "roomId") Long roomId) {
        LiveRoomVO livingRoom = liveRoomService.getLivingRoomInfo(null, roomId);
        if (Objects.isNull(livingRoom)) {
            // 直播间不存在，请刷新后重试
            throw new YamiShopBindException("yami.live.not.exist");
        }
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(livingRoom.getShopId());
        livingRoom.setShopName(shopDetail.getShopName());
        livingRoom.setShopLogo(shopDetail.getShopLogo());
        livingRoom.setChannelId(WuKongConstant.LIVE_CHANNEL_PREFIX + roomId);
        return ServerResponseEntity.success(livingRoom);
    }

    @GetMapping("/pageLivingRoomProd")
    @Operation(summary = "根据房间id获取直播间商品信息列表")
    public ServerResponseEntity<IPage<LiveRoomProdVO>> pageLivingRoomProd(PageParam<LiveRoomProdVO> page,
                                                                          @RequestParam Long roomId) {
        List<LiveRoomProdVO> liveProdList = liveRoomProdService.listLiveRoomProd(roomId);
        if (CollUtil.isEmpty(liveProdList)) {
            IPage<LiveRoomProdVO> param = new PageParam<>();
            param.setPages(page.getPages());
            param.setRecords(Collections.emptyList());
            param.setTotal(0);
            return ServerResponseEntity.success(param);
        }
        // 补充商品信息
        List<Long> prodIds = liveProdList.stream().map(LiveRoomProdVO::getProdId).toList();
        EsProductParam productParam = new EsProductParam();
        productParam.setProdIds(prodIds);
        productParam.setStatus(ProdStatusEnums.NORMAL.getValue());
        productParam.setSort(NON_SORT);
        EsSearchProdEvent esSearchProdEvent = new EsSearchProdEvent();
        esSearchProdEvent.setProductParam(productParam);
        esSearchProdEvent.setPageParam(page);
        eventPublisher.publishEvent(esSearchProdEvent);
        PageParam<EsProductSearchVO> productSearchPage = esSearchProdEvent.getProductSearchPage();
        if (CollUtil.isEmpty(productSearchPage.getRecords())) {
            IPage<LiveRoomProdVO> param = new PageParam<>();
            param.setPages(page.getPages());
            param.setRecords(Collections.emptyList());
            param.setTotal(0);
            return ServerResponseEntity.success(param);
        }
        List<LiveRoomProdVO> liveRoomProdVOList = loadData(productSearchPage.getRecords(), liveProdList);
        IPage<LiveRoomProdVO> param = new PageParam<>();
        param.setPages(productSearchPage.getPages());
        param.setRecords(liveRoomProdVOList);
        param.setTotal(productSearchPage.getTotal());
        param.setSize(productSearchPage.getSize());
        param.setCurrent(productSearchPage.getCurrent());
        return ServerResponseEntity.success(param);
    }

    @GetMapping("/getPullUrl")
    @Operation(summary = "获取播流地址", description = "获取播流地址")
    @Parameters({
            @Parameter(name = "roomId", description = "直播间id"),
            @Parameter(name = "playBackType", description = "播放类型 1.rtmp 2.flv 3.m3u8")
    })
    public ServerResponseEntity<String> getPullUrl(@RequestParam Long roomId, @RequestParam Integer playBackType) {
        AliLive aliLive = shopConfig.getAliLive();
        if (Objects.isNull(aliLive) || StrUtil.isBlank(aliLive.getAppName())) {
            // 无法获取到直播配置
            throw new YamiShopBindException("yami.live.config.not.exist");
        }
        LiveRoomVO livingRoom = liveRoomService.getLivingRoomInfo(null, roomId);
        if (Objects.isNull(livingRoom)) {
            // 直播间不存在，请刷新后重试
            throw new YamiShopBindException("yami.live.not.exist");
        }
        if (Objects.equals(livingRoom.getLiveStatus(), LiveRoomStatusType.FINISHED.value())) {
            // 直播间不存在，请刷新后重试
            throw new YamiShopBindException("yami.live.not.exist");
        }
        if (Objects.isNull(PlayBackType.instance(playBackType))) {
            // 播放类型错误
            throw new YamiShopBindException("yami.live.playBackType.error");
        }
        // 不超过256字符 支持数字、大小写字母、短划线(-)、下划线(_)、等号(=)
        // {appName}-{roomId}-{shopId}-{userId}
        String streamName = StrUtil.format("{}-{}-{}-{}", aliLive.getAppName(), livingRoom.getRoomId(), livingRoom.getShopId(), livingRoom.getUserId());
        String pullUrl = AliLiveUtil.getPullUrl(streamName, playBackType, livingRoom.getEndTime(), aliLive);
        return ServerResponseEntity.success(pullUrl);
    }

    private List<LiveRoomProdVO> loadData(List<EsProductSearchVO> list, List<LiveRoomProdVO> liveProdList) {
        List<LiveRoomProdVO> productList = new ArrayList<>();
        Map<Long, LiveRoomProdVO> liveRoomProdMap = liveProdList.stream().collect(Collectors.toMap(LiveRoomProdVO::getProdId, l -> l));
        for (EsProductSearchVO productSearchVO : list) {
            List<ProductSearchVO> products = productSearchVO.getProducts();
            //商品可用优惠券
            eventPublisher.publishEvent(new EsProductCouponInfoEvent(products));
            for (ProductSearchVO product : products) {
                LiveRoomProdVO liveRoomProdVO = liveRoomProdMap.get(product.getProdId());
                if (Objects.isNull(liveRoomProdVO)) {
                    continue;
                }
                liveRoomProdVO.setProduct(product);
                productList.add(liveRoomProdVO);
            }
        }
        // 排序要跟后台页面的商品顺序一样
        productList.sort(Comparator.comparing(LiveRoomProdVO::getRoomProdId));
        return productList;
    }
}
